<template>
  <div @click="renderScore"
       style="display:inline-block">
    <canvas :id="canvasId"
            :width="width"
            :height="height"></canvas>
  </div>
</template>

<script lang="ts">
import { Vue, Component, Watch, Prop } from "vue-property-decorator";
// import progress from "@/examples/progress/index.vue";
// 每个组件必须加
@Component
export default class DdProgress extends Vue {
  // canvasId
  canvasId: string = "";
  // 画图开始计数
  start1: number = 0;
  // 进度条
  process: number = 0;

  width: number = 200;
  height: number = 200;
  fontSize: number = 72;
  raduis: number = 90;
  lineWidth: number = 20;

  @Prop({
    type: Number,
    default() {
      return 0;
    }
  })
  progress!: number;

  @Prop({
    type: Boolean,
    default() {
      return false;
    }
  })
  isCircle!: boolean;

  @Prop({
    type: String,
    default() {
      // large, medium, small, mini
      return "large";
    }
  })
  size!: string;

  // 创建随机的4位字母id
  createdId(b: number) {
    let str = "aporhjbmvncjrksdsfnsdnsjsolamlmoilovmbxvzzoeclolmqlpvsdffgfgfhhdhfdhdjnmcsdv";
    let canvasId = "";
    for (let i = 0; i < b; i++) {
      let aa = Math.floor(Math.random() * str.length);
      canvasId += str.substring(aa, aa + 1);
    }
    return canvasId;
  }

  // 颜色计算
  cubicEaseOut(t: number, b: number, c: number, d: number): number {
    return c * ((t = t / d - 1) * t * t + 1) + b;
  }

  // 刷新 画图
  loading(
    percent: any,
    circleLoading: any,
    ctx: any,
    circleX: number,
    circleY: number,
    fontSize: number,
    tocolor: any,
    radius: number,
    lineWidth: number
  ): void {
    // 当大于等于清除定时器
    if (this.process >= percent) {
      clearInterval(circleLoading);
    }
    // 画一个框
    ctx.clearRect(0, 0, circleX * 2, circleY * 2);
    // 中间的字 字体的样式
    ctx.font = fontSize + "px Microsoft YaHei";
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    // 计算颜色，返回的颜色 r g b
    let rbb = this.cubicEaseOut(this.start1, 255, tocolor[0] - 255, 200);
    let g = this.cubicEaseOut(this.start1, 51, tocolor[1] - 51, 200);
    let b = this.cubicEaseOut(this.start1, 51, tocolor[2] - 51, 200);
    // 颜色计数器
    this.start1++;
    if (this.isCircle) {
      // 圆形
      this.circle(ctx, circleX, circleY, radius, lineWidth);
      //  圆弧
      this.sector(
        ctx,
        circleX,
        circleY,
        radius,
        (Math.PI * 2) / 3,
        this.process,
        tocolor,
        lineWidth
      );
    }

    // 字体颜色
    ctx.fillStyle =
      "rgba(" + [rbb.toFixed(0), g.toFixed(0), b.toFixed(0)].join() + ", 0.9)";
    // 填充字体颜色
    ctx.fillText(this.process.toFixed(0), circleX, circleY);

    if (this.process / percent > 0.9) {
      this.process += 0.3;
    } else if (this.process / percent > 0.8) {
      this.process += 0.55;
    } else if (this.process / percent > 0.7) {
      this.process += 0.75;
    } else {
      this.process += 1.0;
    }
  }

  // 清除定时器
  refreshCount(circleLoading: any) {
    clearInterval(circleLoading);
  }

  circle(ctx, cx, cy, r, lineWidth: number = 90) {
    ctx.beginPath();
    // ctx.moveTo(cx + r, cy);
    ctx.lineWidth = lineWidth;
    ctx.strokeStyle = "#eee";
    ctx.arc(cx, cy, r, Math.PI * 0, Math.PI * 2);
    ctx.stroke();
  }

  // 画弧线
  sector(
    ctx,
    cx,
    cy,
    r,
    startAngle,
    endAngle,
    tocolor: any,
    lineWidth: number = 20
  ): void {
    ctx.beginPath();
    ctx.lineWidth = lineWidth;
    ctx.strokeStyle = "rgb(255,51,51, 0.9)";
    var rbb = this.cubicEaseOut(this.start1, 255, tocolor[0] - 255, 200);
    var g = this.cubicEaseOut(this.start1, 51, tocolor[1] - 51, 200);
    var b = this.cubicEaseOut(this.start1, 51, tocolor[2] - 51, 200);
    ctx.strokeStyle =
      "rgba(" + [rbb.toFixed(0), g.toFixed(0), b.toFixed(0)].join() + ", 0.9)";
    //  圆弧两端的样式
    ctx.lineCap = "round";

    // 圆弧
    ctx.arc(
      cx,
      cy,
      r,
      -0.5 * Math.PI,
      -0.5 * Math.PI + (endAngle / 100) * (Math.PI * 2),
      false
    );
    ctx.stroke();
  }

  // 画图
  toCanvas(progress: number | string) {
    let vm = this;
    let canvas = document.getElementById(this.canvasId) as HTMLCanvasElement;
    let ctx = canvas.getContext("2d");
    let tocolor: any = [];
    if (progress < 80) {
      tocolor = [255, 200, 51];
    } else if (progress < 60) {
      tocolor = [255, 153, 52];
    } else if (progress < 40) {
      tocolor = [255, 102, 52];
    } else if (progress < 20) {
      tocolor = [255, 51, 52];
    } else {
      tocolor = [3, 188, 120];
    }
    let percent = progress;
    // 最终百分比
    let circleX = canvas.width / 2;
    // 中心x坐标
    let circleY = canvas.height / 2;
    // 中心y坐标
    let fontSize = this.fontSize; // 字体大小
    let start1 = 0;

    let process = 0.0; // 进度

    let radius = this.raduis;

    let lineWidth = this.lineWidth;

    let circleLoading = window.setInterval(function() {
      vm.loading(
        percent,
        circleLoading,
        ctx,
        circleX,
        circleY,
        fontSize,
        tocolor,
        radius,
        lineWidth
      );
    }, 20);
    // 5秒后 去掉上面的定时器
    // let t1 = window.setTimeout(vm.refreshCount, 1000 * 3);
    let t1 = window.setTimeout(function() {
      clearInterval(circleLoading);
    }, 1000 * 3);
    // 去掉定时器的方法
    clearTimeout(t1);
  }

  created() {
    // medium, small, mini
    switch (this.size) {
      case "large":
        this.width = 200;
        this.height = 200;
        this.fontSize = 72;
        this.raduis = 90;
        this.lineWidth = 20;
        break;
      case "medium":
        this.width = 150;
        this.height = 150;
        this.fontSize = 54;
        this.raduis = 66;
        this.lineWidth = 15;
        break;
      case "small":
        this.width = 100;
        this.height = 100;
        this.fontSize = 36;
        this.raduis = 44;
        this.lineWidth = 10;
        break;
      case "mini":
        this.width = 50;
        this.height = 50;
        this.fontSize = 18;
        this.raduis = 22;
        this.lineWidth = 5;
        break;
    }
    this.canvasId = this.createdId(4);
  }

  renderScore(): void {
    this.start1 = 0;
    // 进度条
    this.process = 0;
    if (this.progress > 100) {
      this.toCanvas(100);
    } else if (this.progress < 0) {
      this.toCanvas(0);
    } else {
      this.toCanvas(this.progress);
    }
  }

  mounted() {
    this.renderScore();
  }
}
</script>

<style>
</style>